package com.management.department.teacherinfosystem.Controller;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.management.department.teacherinfosystem.Entity.Attachment;
import com.management.department.teacherinfosystem.Entity.Award;
import com.management.department.teacherinfosystem.Entity.User;
import com.management.department.teacherinfosystem.Repository.AttachmentRepository;
import com.management.department.teacherinfosystem.Repository.AwardRepository;
import com.management.department.teacherinfosystem.Repository.UserRepository;

@RestController
@RequestMapping("/api/awards")
@CrossOrigin(origins = "*")
public class AwardController {

	@Autowired
	private AwardRepository awardRepository;
	@Autowired
	private UserRepository userRepository;
	@Autowired
	private AttachmentRepository attachmentRepository;

	@Value("${file.upload.award-dir:/uploads/awards/}")
	private String awardUploadDir;

	private File ensureAwardDir() {
		String base = awardUploadDir;
		if (base == null || base.isBlank()) base = "/uploads/awards/";
		// 兼容 Windows 路径，确保以分隔符结尾
		if (!base.endsWith("/") && !base.endsWith("\\")) {
			base = base + File.separator;
		}
		File dir = new File(base);
		if (!dir.exists()) dir.mkdirs();
		this.awardUploadDir = base; // 纠正尾部分隔符
		return dir;
	}

	@PostMapping
	@Transactional
	public ResponseEntity<?> createAward(@RequestBody Map<String, Object> payload) {
		try {
			org.springframework.security.core.Authentication auth =
					org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
			String currentUsername = auth.getName();
			User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
			if (currentUser == null) return ResponseEntity.status(401).body("用户未登录");

			Award a = new Award();
			a.setAwardName((String) payload.getOrDefault("award_name", null));
			a.setAchievementName((String) payload.getOrDefault("achievement_name", null));
			a.setCategory((String) payload.getOrDefault("category", null));
			a.setLevel((String) payload.getOrDefault("level", null));
			a.setGrade((String) payload.getOrDefault("grade", null));
			a.setAwardingOrg((String) payload.getOrDefault("awarding_org", null));
			Object ad = payload.get("awarding_date");
			if (ad != null) {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					a.setAwardingDate(sdf.parse(String.valueOf(ad)));
				} catch (Exception ignored) {}
			}
			a.setCertificateNo((String) payload.getOrDefault("certificate_no", null));
			a.setRelatedType((String) payload.getOrDefault("related_type", "INDEPENDENT"));
			Object rid = payload.get("related_id");
			if (rid != null) a.setRelatedId(Long.valueOf(String.valueOf(rid)));
			a.setStatus("PENDING");
			a.setCreatedBy(currentUser.getId());
			a.setCreatedAt(new Date());
			a.setUpdatedAt(new Date());

			Award saved = awardRepository.save(a);
			return ResponseEntity.ok(Map.of("id", saved.getId()));
		} catch (Exception e) {
			return ResponseEntity.status(500).body(e.getMessage());
		}
	}

	@GetMapping("/mine")
	@Transactional(readOnly = true)
	public ResponseEntity<?> myAwards() {
		org.springframework.security.core.Authentication auth =
				org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
		String currentUsername = auth.getName();
		User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
		if (currentUser == null) return ResponseEntity.status(401).body("用户未登录");
		return ResponseEntity.ok(awardRepository.findByCreatedBy(currentUser.getId()));
	}

	@GetMapping("/pending")
	@Transactional(readOnly = true)
	public ResponseEntity<?> getPendingAwards() {
		org.springframework.security.core.Authentication auth =
				org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
		String currentUsername = auth.getName();
		User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
		if (currentUser == null) return ResponseEntity.status(401).body("用户未登录");
		
		boolean isAdmin = currentUser.getUserRoles().stream()
				.anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
		if (!isAdmin) {
			return ResponseEntity.status(403).body("权限不足");
		}
		
		List<Award> pendingAwards = awardRepository.findByStatus("PENDING");
		return ResponseEntity.ok(pendingAwards);
	}

	@GetMapping("/all")
	@Transactional(readOnly = true)
	public ResponseEntity<?> getAllAwards() {
		org.springframework.security.core.Authentication auth =
				org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
		String currentUsername = auth.getName();
		User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
		if (currentUser == null) return ResponseEntity.status(401).body("用户未登录");
		
		boolean isAdmin = currentUser.getUserRoles().stream()
				.anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
		if (!isAdmin) {
			return ResponseEntity.status(403).body("权限不足");
		}
		
		List<Award> allAwards = awardRepository.findAll();
		// 构建携带申请人姓名的结果集，便于前端直接显示 creatorName
		List<Map<String, Object>> result = new ArrayList<>();
		for (Award a : allAwards) {
			Map<String, Object> m = new HashMap<>();
			m.put("id", a.getId());
			m.put("awardName", a.getAwardName());
			m.put("achievementName", a.getAchievementName());
			m.put("category", a.getCategory());
			m.put("level", a.getLevel());
			m.put("grade", a.getGrade());
			m.put("awardingDate", a.getAwardingDate());
			m.put("awardingOrg", a.getAwardingOrg());
			m.put("status", a.getStatus());
			m.put("createdAt", a.getCreatedAt());
			if (a.getCreatedBy() != null) {
				userRepository.findById(a.getCreatedBy()).ifPresent(u -> m.put("creatorName", u.getName()));
			}
			result.add(m);
		}
		return ResponseEntity.ok(result);
	}

	@PostMapping("/{id:[0-9]+}/review")
	@Transactional
	public ResponseEntity<?> reviewAward(
			@PathVariable("id") Long id,
			@RequestBody Map<String, Object> payload
	) {
		try {
			org.springframework.security.core.Authentication auth =
					org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
			String currentUsername = auth.getName();
			User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
			if (currentUser == null) return ResponseEntity.status(401).body("用户未登录");
			
			boolean isAdmin = currentUser.getUserRoles().stream()
					.anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
			if (!isAdmin) {
				return ResponseEntity.status(403).body("权限不足");
			}
			
			Award award = awardRepository.findById(id).orElse(null);
			if (award == null) return ResponseEntity.notFound().build();
			
			String status = (String) payload.get("status");
			String reviewOpinion = (String) payload.get("reviewOpinion");
			
			if (!"APPROVED".equals(status) && !"REJECTED".equals(status)) {
				return ResponseEntity.badRequest().body("无效的审核状态");
			}
			
			award.setStatus(status);
			award.setReviewOpinion(reviewOpinion);
			award.setReviewerId(currentUser.getId());
			award.setReviewTime(new Date());
			award.setUpdatedAt(new Date());
			
			awardRepository.save(award);
			return ResponseEntity.ok("审核完成");
		} catch (Exception e) {
			return ResponseEntity.status(500).body(e.getMessage());
		}
	}

	@GetMapping("/{id:[0-9]+}")
	@Transactional(readOnly = true)
	public ResponseEntity<?> getAward(@PathVariable("id") Long id) {
		Award award = awardRepository.findById(id).orElse(null);
		if (award == null) {
			return ResponseEntity.notFound().build();
		}
		
		// 构建包含申请人信息的响应
		Map<String, Object> response = new HashMap<>();
		response.put("award", award);
		
		// 获取申请人信息
		if (award.getCreatedBy() != null) {
			User creator = userRepository.findById(award.getCreatedBy()).orElse(null);
			if (creator != null) {
				response.put("creatorName", creator.getName());
				response.put("creatorDepartment", creator.getDepartment());
			}
		}
		
		// 获取审核人信息
		if (award.getReviewerId() != null) {
			User reviewer = userRepository.findById(award.getReviewerId()).orElse(null);
			if (reviewer != null) {
				response.put("reviewerName", reviewer.getName());
			}
		}
		
		return ResponseEntity.ok(response);
	}

	@PutMapping("/{id:[0-9]+}")
	@Transactional
	public ResponseEntity<?> updateAward(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
		try {
			Award a = awardRepository.findById(id).orElse(null);
			if (a == null) return ResponseEntity.notFound().build();
			// 权限：本人可改
			org.springframework.security.core.Authentication auth =
					org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
			String currentUsername = auth.getName();
			User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
			boolean isAdmin = currentUser != null && currentUser.getUserRoles().stream()
					.anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
			if (currentUser == null || (!Objects.equals(a.getCreatedBy(), currentUser.getId()) && !isAdmin)) {
				return ResponseEntity.status(403).body("无权修改");
			}

			a.setAwardName((String) payload.getOrDefault("award_name", a.getAwardName()));
			a.setAchievementName((String) payload.getOrDefault("achievement_name", a.getAchievementName()));
			a.setCategory((String) payload.getOrDefault("category", a.getCategory()));
			a.setLevel((String) payload.getOrDefault("level", a.getLevel()));
			a.setGrade((String) payload.getOrDefault("grade", a.getGrade()));
			a.setAwardingOrg((String) payload.getOrDefault("awarding_org", a.getAwardingOrg()));
			Object ad = payload.get("awarding_date");
			if (ad != null) {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					a.setAwardingDate(sdf.parse(String.valueOf(ad)));
				} catch (Exception ignored) {}
			}
			a.setCertificateNo((String) payload.getOrDefault("certificate_no", a.getCertificateNo()));
			Object st = payload.get("status");
			if (st != null) a.setStatus(String.valueOf(st));
			a.setUpdatedAt(new Date());
			awardRepository.save(a);
			return ResponseEntity.ok("OK");
		} catch (Exception e) {
			return ResponseEntity.status(500).body(e.getMessage());
		}
	}

	@DeleteMapping("/{id:[0-9]+}")
	@Transactional
	public ResponseEntity<?> deleteAward(@PathVariable("id") Long id) {
		Award a = awardRepository.findById(id).orElse(null);
		if (a == null) return ResponseEntity.notFound().build();
		org.springframework.security.core.Authentication auth =
				org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
		String currentUsername = auth.getName();
		User currentUser = userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
		boolean isAdmin = currentUser != null && currentUser.getUserRoles().stream()
				.anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
		if (currentUser == null || (!Objects.equals(a.getCreatedBy(), currentUser.getId()) && !isAdmin)) {
			return ResponseEntity.status(403).body("无权删除");
		}
		attachmentRepository.deleteByRelatedIdAndRelatedType(id, "award");
		awardRepository.deleteById(id);
		return ResponseEntity.ok().build();
	}

	@PostMapping("/{id:[0-9]+}/attachments")
	@Transactional
	public ResponseEntity<?> uploadAttachment(
			@PathVariable("id") Long id,
			@RequestPart("file") MultipartFile file,
			@RequestPart(value = "fileType", required = false) String fileType
	) {
		try {
			Award award = awardRepository.findById(id).orElse(null);
			if (award == null) return ResponseEntity.notFound().build();

			File dir = ensureAwardDir();
			String original = Objects.requireNonNull(file.getOriginalFilename());
			String ext = original.contains(".") ? original.substring(original.lastIndexOf('.')) : "";
			String saveName = System.currentTimeMillis() + "_" + UUID.randomUUID() + ext;
			File dest = new File(dir, saveName);
			file.transferTo(dest);

			Attachment attachment = new Attachment();
			attachment.setFileName(original);
			// 记录可访问路径（保持与配置一致）
			attachment.setFileUrl(awardUploadDir + saveName);
			attachment.setRelatedType("award");
			attachment.setRelatedId(id);
			attachment.setUploadedAt(new Date());
			attachmentRepository.save(attachment);

			if (award.getCertificateUrl() == null || award.getCertificateUrl().isEmpty()) {
				award.setCertificateUrl(attachment.getFileUrl());
				awardRepository.save(award);
			}

			return ResponseEntity.ok(Map.of("url", attachment.getFileUrl()));
		} catch (Exception e) {
			return ResponseEntity.status(500).body(e.getMessage());
		}
	}

	@GetMapping("/{id:[0-9]+}/attachments")
	@Transactional(readOnly = true)
	public List<Attachment> listAttachments(@PathVariable("id") Long id) {
		return attachmentRepository.findByRelatedTypeAndRelatedId("award", id);
	}

	@DeleteMapping("/{id:[0-9]+}/attachments/{attId:[0-9]+}")
	@Transactional
	public ResponseEntity<?> deleteAttachment(@PathVariable("id") Long id, @PathVariable("attId") Long attId) {
		Optional<Attachment> opt = attachmentRepository.findById(attId);
		if (opt.isEmpty()) return ResponseEntity.notFound().build();
		Attachment att = opt.get();
		if (!Objects.equals(att.getRelatedId(), id) || !"award".equals(att.getRelatedType())) {
			return ResponseEntity.status(400).body("附件与奖项不匹配");
		}
		attachmentRepository.deleteById(attId);
		return ResponseEntity.ok().build();
	}
} 